<template>
  <section class="sign-up">
    <el-form ref="form_signUp" :model="form_signUp" :rules="rules_signUp">
      <el-form-item prop="phoneNumber">
        <el-input v-model.number="form_signUp.phoneNumber" autocomplete="off" placeholder="请输入手机号">
          <span v-show="!timer" slot="append" ref="phoneCode" @click="showGifCode(true)">
            发送验证码
          </span>
          <span v-show="timer" slot="append" ref="phoneCode">
            {{ btnContent }}
          </span>
        </el-input>
      </el-form-item>
      <el-form-item prop="phoneCodeValue">
        <el-input v-model="form_signUp.phoneCodeValue" autocomplete="off" placeholder="请输入验证码" />
      </el-form-item>
      <el-form-item prop="password">
        <el-input v-model="form_signUp.password" type="password" autocomplete="off" placeholder="请输入密码" />
      </el-form-item>
      <el-form-item prop="checkPassword">
        <el-input v-model="form_signUp.checkPassword" type="password" autocomplete="off" placeholder="请再次输入密码" />
      </el-form-item>
    </el-form>
    <button class="btn-submit" @click="submitForm('form_signUp')">
      注册
    </button>

    <el-dialog
      width="30%"
      title="安全验证"
      :visible.sync="isShowGifCode"
      :lock-scroll="false"
      append-to-body
    >
      <gif-code @closeGifCode="showGifCode" />
    </el-dialog>
  </section>
</template>

<script>
// 引入工具
import { isPhone } from '~/assets/js/util.js'

// 引入组件
import GifCode from './GifCode'

export default {
  name: 'SignUp',
  components: { GifCode },
  data() {
    const validatePhoneNumber = async (rule, value, callback) => {
      this.isUsablePhoneNumber = false
      let params = {}
      if (value === '') {
        callback(new Error('请输入手机号'))
        return
      } else if (isPhone(value)) {
        params = {
          phone: value
        }
      } else {
        callback(new Error('请输入正确的手机号'))
        return
      }

      // 检测手机号是否已注册
      try {
        const res = await this.$axios.$post('/api/code/check', params)
        if (res.status === 200) {
          callback()
          this.isUsablePhoneNumber = true
        } else {
          callback(new Error(res.msg))
        }
      } catch (err) {
        callback(new Error(err))
      }
    }
    const validatePassword = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请再次输入密码'))
      } else if (value !== this.form_signUp.password) {
        callback(new Error('两次输入密码不一致!'))
      } else {
        callback()
      }
    }
    return {
      isShowGifCode: false,
      isUsablePhoneNumber: false,
      timeout: 60,
      btnContent: '60 秒后重新发送',
      timer: null,
      form_signUp: {
        phoneNumber: '',
        password: '',
        checkPassword: '',
        phoneCode: '',
        phoneCodeValue: ''
      },
      rules_signUp: {
        phoneCodeValue: [
          {
            required: true,
            message: '请输入验证码',
            trigger: 'blur'
          }
        ],
        phoneNumber: [
          {
            validator: validatePhoneNumber,
            trigger: 'blur'
          }
        ],
        password: [
          {
            required: true,
            min: 8,
            max: 16,
            message: '密码为8~16位',
            trigger: 'blur'
          }
        ],
        checkPassword: [
          {
            validator: validatePassword,
            trigger: 'blur'
          }
        ]
      }
    }
  },
  methods: {
    showGifCode(boolean) {
      setTimeout(() => {
        if (this.isUsablePhoneNumber) {
          if (this.isShowGifCode) {
            // 如果为 true 则为 gifCode 关闭前状态，此时触发 triggerTimeout
            this.triggerTimeout()
          }
          this.isShowGifCode = boolean
        }
      }, 1000)
    },
    triggerTimeout() {
      console.log('getPhoneCode')
      this.getPhoneCode()
      // 触发倒计时
      this.timer = setInterval(() => {
        this.btnContent = --this.timeout + ' 秒后重新发送'
        if (this.timeout <= 0) {
          clearInterval(this.timer)
          this.btnContent = '60 秒后重新发送'
          this.timeout = 60
          this.timer = null
        }
      }, 1000)
    },
    async getPhoneCode() {
      try {
        const res = await this.$axios.$get('/api/code/getPhoneCode/r/' + this.form_signUp.phoneNumber)
        if (res.status === 200) {
          this.form_signUp.phoneCode = res.data
          this.$message.success(res.msg)
        } else {
          this.$message.error(res.msg)
        }
      } catch (err) {
        this.$message.error(err)
      }
    },
    async postSignUp() {
      let params = {}
      try {
        params = {
          'password': this.form_signUp.password,
          'phone': this.form_signUp.phoneNumber,
          'phoneCode': this.form_signUp.phoneCode,
          'phoneCodeValue': this.form_signUp.phoneCodeValue
        }
        const res = await this.$axios.$post('/api/user/register', params)
        if (res.status === 200) {
          // 跳转登录
          this.$emit('toSignIn', this.form_signUp.phoneNumber)
          // 重置表单
          this.resetForm('form_signUp')
          this.$message.success(res.msg)
        } else {
          this.$message.error(res.msg)
        }
      } catch (err) {
        this.$message.error(err)
      }
    },
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.postSignUp()
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    resetForm(formName) {
      this.$refs[formName].resetFields()
    }
  }
}
</script>

<style scoped lang="scss">

  @import "~assets/css/public";
  .sign-up {
    /deep/ .el-form {
      .el-form-item {
        .el-input {
          .el-input-group__append {
            background: none;
            border: none;
            border-bottom: 2px solid $theme-color-background;
            font-size: 12px;
            color: $theme-color;
            padding-right: 6px;
            span {
              cursor: pointer;
              display: inline-block;
              margin-top: -2px;
            }
          }
        }
      }
    }
  }
</style>
